-- Winter Anathema (c) v.v.balashoff
local CircleComponent = require('leviathan/ECS/UI/Components/CircleComponent')
local Domain = require('leviathan/ECS/Domain')
local Entity = require('leviathan/ECS/Entity')
local Log = require('leviathan/Log')
local MouseClickComponent = require('leviathan/ECS/UI/Components/MouseClickComponent')
local MouseHoverComponent = require('leviathan/ECS/UI/Components/MouseHoverComponent')
local RectangleComponent = require('leviathan/ECS/UI/Components/RectangleComponent')
local SliderComponent = require('leviathan/ECS/UI/Components/SliderComponent')
local SliderOffsetComponent = require('leviathan/ECS/UI/Components/SliderOffsetComponent')
local TextureComponent = require('leviathan/ECS/UI/Components/TextureComponent')
local TweenComponent = require('leviathan/ECS/UI/Components/TweenComponent')
local ViewerComponent = require('leviathan/ECS/UI/Components/ViewerComponent')
local UIHoverSystem = require('leviathan/ECS/UI/Systems/HoverSystem')
local UIInputSystem = require('leviathan/ECS/UI/Systems/InputSystem')
local UIMouseWheelSystem = require('leviathan/ECS/UI/Systems/MouseWheelSystem')
local UIRenderSystem = require('leviathan/ECS/UI/Systems/RenderSystem')
local UISliderSystem = require('leviathan/ECS/UI/Systems/SliderSystem')
local UISliderOffsetSystem = require('leviathan/ECS/UI/Systems/SliderOffsetSystem')
local UITweenSystem = require('leviathan/ECS/UI/Systems/TweenSystem')
local UIViewerSystem = require('leviathan/ECS/UI/Systems/ViewerSystem')

local DomainAbout = Domain:derive('About')

function DomainAbout:new(world)
    -- call parent constructor
    DomainAbout.super.new(self, world, 'About')
    -- get managers
    local ImagesManager = world:getManager('ImagesManager')
    -- size calculations
    local screenW, screenH = love.window.getMode()
    -- images
    local coverTexture = ImagesManager:getImageTexture('Concrete_001')
    local bTexture = ImagesManager:getImageTexture('RedCross')
    local bHighTexture = ImagesManager:getImageTexture('PaintStroke')
    -- cover
    local coverW = screenW * 0.96 -- 96% of screen width
    local coverH = screenH * 0.96 -- 96% of screen height
    -- view
    local viewX = math.floor(screenW * 0.01) -- 1% of screen width
    local viewY = math.floor(screenH * 0.04) -- 4% of screen height
    local viewW = math.floor(screenW * 0.95) -- 95% of screen width
    local viewH = math.floor(screenH * 0.91) -- 91% of screen height
    -- close button
    local closeH = math.floor(screenH * 0.03) -- 3% of screen width
    local closeW = closeH
    local closeX = coverW - closeW
    local closeY = 0
    -- slider coordinates (NOTE: should be sync with AboutContent!)
    local sliderW = math.floor(screenW * 0.015) -- 1.5% of screen width
    local sliderX = math.floor(screenW * 0.942) -- 94.2% of screen width
    local sliderY = math.floor(screenH * 0.05) -- 5% of screen width
    local sliderH = math.floor(screenH * 0.89) -- 89% of screen height
    -- set buffer size
    self.buffer.worldX = math.floor(coverW * 0.02)
    self.buffer.worldY = math.floor(1.2 * screenH)
    self.buffer.w = coverW
    self.buffer.h = coverH

    -- entity: cover
    local cover = Entity(self, 'AboutCover', 0, 0, coverW, coverH)
    local coverTextureComp = TextureComponent(coverTexture.texture, 0, 0, coverW, coverH, 'center', 'center', false, 0.5)
    cover:addComponent(coverTextureComp)
    -- entity: buttonClose
    local bClose = Entity(self, 'ButtonClose', closeX, closeY, closeW, closeH)
    cover:addChild(bClose)
    -- button Close hover
    local btnCloseMouseHoverComp = MouseHoverComponent(self.buttonCloseHoverOn, self.buttonCloseHoverOff)
    bClose:addComponent(btnCloseMouseHoverComp)
    -- button Close normal
    local bCloseNorm = Entity(self, 'bCloseNorm', closeX, y, coverW, closeH)
    local bCloseTextureNorm = TextureComponent(bTexture.texture, 0, 0, closeW, closeH, 'center', 'bottom', false)
    bCloseNorm:addComponent(bCloseTextureNorm)
    cover:addChild(bCloseNorm)
    bCloseNorm:setPriority(800)
    -- button Close high
    local bCloseHigh = Entity(self, 'bCloseHigh', closeX, y, coverW, closeH)
    local bCloseTextureHigh = TextureComponent(bHighTexture.texture, 0, 0, closeW, closeH, 'center', 'bottom', false)
    bCloseHigh:addComponent(bCloseTextureHigh)
    cover:addChild(bCloseHigh)
    bCloseHigh:setPriority(750)
    bCloseHigh.enabled = false
    -- button Close click
    local bCloseClickComponent = MouseClickComponent(self.buttonCloseClick, 'MouseLeftButton', 'ButtonAsyncPressedComponent')
    bClose:addComponent(bCloseClickComponent)
    -- entity: viewer
    local viewer = Entity(self, 'Viewer', viewX, viewY, viewW, viewH)
    local vComp = ViewerComponent('ViewerComponent', 0, 0, nil)
    viewer:addComponent(vComp)
    -- entity: knob
    local knob = Entity(self, 'Knob', sliderX, sliderY, sliderW, sliderH)
    local knobComponent = CircleComponent('fill', sliderW/2, 0, sliderW/2)
    knob:addComponent(knobComponent)
    -- entity: slider
    local scroller = Entity(self, 'Scroller', sliderX, sliderY, sliderW, sliderH)
    local rect = RectangleComponent('line', 0, -sliderW/2, sliderW, sliderH + sliderW, sliderW/2, sliderW/2)
    scroller:addComponent(rect)
    local sliderComp = SliderComponent('SliderComponent', sliderX, sliderY, 0, sliderH)
    scroller:addComponent(sliderComp)
    local scrollerMouseClickComp = MouseClickComponent()
    scroller:addComponent(scrollerMouseClickComp)
    local scrollerMouseHoverComp = MouseHoverComponent()
    scroller:addComponent(scrollerMouseHoverComp)
    cover:addChild(scroller)
    -- slider knob offset
    local knobOffset = Entity(self, 'KnobOffset', sliderX, sliderY, sliderW, sliderH)
    local knobOffsetComponent = SliderOffsetComponent('KnobOffset', sliderX, sliderY, sliderW, sliderH, sliderComp, knob, 'y')
    knobOffset:addComponent(knobOffsetComponent)
    -- entity: tweenIn
    local tweenIn = Entity(self, 'TweenIn', 0, 0, 0, 0)
    tweenIn.enabled = false
    local tweenInComp = TweenComponent(2.0, self.buffer, {worldY = (screenH - coverH) * 0.5}, 'inOutCubic')
    tweenIn:addComponent(tweenInComp)
    -- entity: tweenOut
    local tweenOut = Entity(self, 'TweenOut', 0, 0, 0, 0)
    tweenOut.enabled = false
    local tweenOutComp = TweenComponent(2.0, self.buffer, {worldY = coverH * 1.2}, 'inOutCubic')
    tweenOut:addComponent(tweenOutComp)
    -- systems
    local render = UIRenderSystem(self)
    local input = UIInputSystem(self)
    local hover = UIHoverSystem(self)
    local sliderSys = UISliderSystem(self)
    local sliderOffsetSys = UISliderOffsetSystem(self)
    local wheelSys = UIMouseWheelSystem(self)
    local tween = UITweenSystem(self)
    local viewerSys = UIViewerSystem(self)
    -- adding systems
    DomainAbout:addSystem(self, render)
    DomainAbout:addSystem(self, input)
    DomainAbout:addSystem(self, hover)
    DomainAbout:addSystem(self, sliderSys)
    DomainAbout:addSystem(self, sliderOffsetSys)
    DomainAbout:addSystem(self, wheelSys)
    DomainAbout:addSystem(self, tween, 410)
    DomainAbout:addSystem(self, viewerSys)
end

function DomainAbout:onEnter()
    self:slideIn()
    -- summon content domain
    world:getDomain('AboutContent')
end

function DomainAbout:onExit()
    self:slideOut()
end

-- ----------

-- buttons hover

function DomainAbout:buttonCloseHoverOn()
    local domain = self.entity.domain
--    domain:getEntity('bCloseNorm').enabled = false
    domain:getEntity('bCloseHigh').enabled = true
    domain.changed = true
end

function DomainAbout:buttonCloseHoverOff()
    local domain = self.entity.domain
--    domain:getEntity('bCloseNorm').enabled = true
    domain:getEntity('bCloseHigh').enabled = false
    domain.changed = true
end

function DomainAbout:buttonCloseClick(domain, button)
    -- sound
    local audio = world:getDomain('Audio')
    audio:playSound('accept')
    -- return back to MainMenu
    Log:info('[About] => [MainMenu]')
    world:switchDomain(self, 'MainMenu', true)
end

function DomainAbout:slideIn()
    local domain = world:getDomain('About')
    local entityIn = domain:getEntity('TweenIn')
    local comp = entityIn:getComponent('TweenComponent')
    comp.tween:reset()
    entityIn.enabled = true
    local entityOut = domain:getEntity('TweenOut')
    entityOut.enabled = false
end

function DomainAbout:slideOut()
    local domain = world:getDomain('About')
    local entityIn = domain:getEntity('TweenIn')
    entityIn.enabled = false
    local entityOut = domain:getEntity('TweenOut')
    local comp = entityOut:getComponent('TweenComponent')
    comp.tween:reset()
    entityOut.enabled = true
end

return DomainAbout
